﻿using Caliburn.Micro;
using HandyControl.Controls;
using HandyControl.Data;
using JY.Wpf.Controls.Controls;
using JY.Wpf.Core.Enums;
using JY.Wpf.Core.Events;
using JY.Wpf.Core.Tools;
using JY.Wpf.Core.ViewModelBases;
using SlamDunk.MES.DataDrive.Common;
using SlamDunk.MES.DataDrive.Common.Attributes;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace SlamDunk.MES.DataDrive.Client.ViewModels
{
    /// <summary>
    /// 主页面ViewModel
    /// </summary>
    public class ShellViewModel : MainViewModelBase
    {
        #region # 变量
        private bool _isFullScreen;
        private ObservableCollection<ImportDataMenu> _importDataMenus;
        private ImportDataMenu _selectedImportDataMenu;
        private int _stepIndex;
        private IGrouping<DataTagAttribute, DataMenu> _stepItem;
        private DataMenu _selectedItem;
        #endregion

        #region # 构造器
        /// <summary>
        /// 构造器
        /// </summary>
        public ShellViewModel()
        {
            WarningMessageBar.Initialize((m) => { });
            this.InitView();
        }
        #endregion

        #region # 属性
        #region # 数据驱动菜单——ObservableCollection<ImportDataMenu> ImportDataMenus
        /// <summary>
        /// 数据驱动菜单
        /// </summary>
        public ObservableCollection<ImportDataMenu> ImportDataMenus
        {
            get { return this._importDataMenus; }
            set { this._importDataMenus = value; base.NotifyOfPropertyChange(); }
        }
        #endregion

        #region # 选中的数据驱动菜单组——ImportDataMenu SelectedImportDataMenu
        /// <summary>
        /// 选中的数据驱动菜单组
        /// </summary>
        public ImportDataMenu SelectedImportDataMenu
        {
            get { return this._selectedImportDataMenu; }
            set
            {
                this._selectedImportDataMenu = value;
                base.NotifyOfPropertyChange();
                this.StepIndex = 0;
                this.StepItem = this.SelectedImportDataMenu.SubMethodMenus[this.StepIndex];
            }
        }
        #endregion

        #region # 步骤条当前步骤—— int StepIndex
        /// <summary>
        /// 步骤条当前步骤项
        /// </summary>
        public int StepIndex
        {
            get { return this._stepIndex; }
            set { this._stepIndex = value; base.NotifyOfPropertyChange(); }
        }
        #endregion

        #region # 步骤条当前步骤项—— IGrouping<DataTagAttribute, DataMenu> StepItem
        /// <summary>
        /// 步骤条当前步骤项
        /// </summary>
        public IGrouping<DataTagAttribute, DataMenu> StepItem
        {
            get { return this._stepItem; }
            set { this._stepItem = value; base.NotifyOfPropertyChange(); }
        }
        #endregion

        #region 选中行属性
        public DataMenu SelectedItem
        {
            get { return this._selectedItem; }
            set { this._selectedItem = value; base.NotifyOfPropertyChange(); }
        }
        #endregion

        #region # 是否全屏——bool IsFullScreen
        /// <summary>
        /// 是否全屏
        /// </summary>
        public bool IsFullScreen
        {
            get { return this._isFullScreen; }
            set { this._isFullScreen = value; base.NotifyOfPropertyChange(); }
        }
        #endregion
        #endregion

        #region # Command方法

        #region # 全屏——void FullScreen()
        /// <summary>
        /// 全屏
        /// </summary>
        public void FullScreen()
        {
            this.IsFullScreen = true;
        }
        #endregion

        #region # 取消全屏——void CancleFullScreen()
        /// <summary>
        /// 取消全屏
        /// </summary>
        public void CancleFullScreen()
        {
            this.IsFullScreen = false;
        }
        #endregion

        #region # 步骤条变更方法——void StepChanged(StepBar stepBar)
        /// <summary>
        /// 步骤条变更方法
        /// </summary>
        public void StepChanged(StepBar stepBar)
        {
            this.StepItem = this.SelectedImportDataMenu.SubMethodMenus[stepBar.StepIndex];
        }
        #endregion

        #region # 执行一条数据——void RunDataMenu(Button dataMenuButton)
        /// <summary>
        /// 执行一条数据
        /// </summary>
        /// <param name="dataMenuButton">执行按钮</param>
        public async void RunDataMenu(Button dataMenuButton)
        {
            DataMenu dataMenu = dataMenuButton.Tag as DataMenu;
            if (dataMenu == null) return;
            this.EventAggregator.PublishOnUIThread(new BusyIndicatorEvent(true, $"数据【{dataMenu.MethodDataTag.Name}】执行中..."));
            //调用执行方法
            await Task.Run(() => { this.RunDataBase(dataMenu); });
            this.EventAggregator.PublishOnUIThread(new BusyIndicatorEvent(false));
            Growl.Success(new GrowlInfo() { Message = "执行完成", ShowDateTime = true });
        }
        #endregion

        #region # 一键执行当前步骤——void RunCurStep()
        /// <summary>
        /// 一键执行当前步骤
        /// </summary>
        public async void RunCurStep()
        {
            //获取没有执行的方法集合
            List<DataMenu> dataMenus = this.StepItem.Where(x => !x.IsExecute).ToList();

            //根据执行顺序循环方法
            foreach (var dataMenu in dataMenus.OrderBy(x => x.MethodDataTag.Sort))
            {
                this.SelectedItem = dataMenu;
                this.EventAggregator.PublishOnUIThread(new BusyIndicatorEvent(true, $"数据【{dataMenu.MethodDataTag.Name}】执行中..."));
                //调用执行方法
                await Task.Run(() => { this.RunDataBase(dataMenu); });
                this.EventAggregator.PublishOnUIThread(new BusyIndicatorEvent(false));
            }

            Growl.Success(new GrowlInfo() { Message = "执行完成", ShowDateTime = true });
        }
        #endregion

        #region # 执行全部——void RunAll()
        /// <summary>
        /// 执行全部
        /// </summary>
        public async void RunAll()
        {
            //循环方法大类
            foreach (IGrouping<DataTagAttribute, DataMenu> selectedDataMenu in this.SelectedImportDataMenu.SubMethodMenus)
            {
                this.StepIndex = this.SelectedImportDataMenu.SubMethodMenus.IndexOf(selectedDataMenu);//切换步骤
                //获取没有执行的方法集合
                List<DataMenu> dataMenus = selectedDataMenu.Where(x => !x.IsExecute && x.TypeDataTag.Name == selectedDataMenu.Key.Name).ToList();

                foreach (var dataMenu in dataMenus.OrderBy(x => x.MethodDataTag.Sort))
                {
                    this.SelectedItem = dataMenu;
                    this.EventAggregator.PublishOnUIThread(new BusyIndicatorEvent(true, $"数据【{dataMenu.MethodDataTag.Name}】执行中..."));
                    //调用执行方法
                    await Task.Run(() => { this.RunDataBase(dataMenu); });
                    this.EventAggregator.PublishOnUIThread(new BusyIndicatorEvent(false));
                }
            }
            Growl.Success(new GrowlInfo() { Message = "执行完成", ShowDateTime = true });
        }
        #endregion

        #region 调用执行方法
        /// <summary>
        /// 调用执行方法
        /// </summary>
        /// <param name="dataMenu"></param>
        public void RunDataBase(DataMenu dataMenu)
        {
            //执行方法
            ReflectionHelper.InvokeMethod(dataMenu);
            //备份数据库
            //DataBaseHelper.BackupsDataBase(dataMenu, SystemConfig.FileDataBase + dataMenu.BackDataBaseFileName);

            dataMenu.IsExecute = true;
        }
        #endregion
        #endregion

        #region # 方法

        #region # 初始化页面——void InitView()
        /// <summary>
        /// 初始化页面
        /// </summary>
        public override void InitView()
        {
            //初始化Bussiness
            ReflectionHelper.InvokeMethodByInterfaceType(SystemConfig.BussinessAssemblyName, typeof(IDataDriveConfig));

            //初始化数据驱动菜单
            List<DataMenu> dataMenus = ReflectionHelper.GetDataMenus(SystemConfig.BussinessAssemblyName);
            List<ImportDataMenu> importDataMenus = new List<ImportDataMenu>();
            List<string> groupNames = dataMenus.Where(x => !string.IsNullOrWhiteSpace(x.TypeDataTag.GroupName)).Select(x => x.TypeDataTag.GroupName).Distinct().OrderBy(x => x).ToList();
            if (groupNames.Any())
            {
                foreach (string groupName in groupNames)
                {
                    var groupNameDataMenus = dataMenus.Where(x => string.IsNullOrWhiteSpace(x.TypeDataTag.GroupName) || x.TypeDataTag.GroupName == groupName).OrderBy(x => x.TypeDataTag.Sort).ToList();
                    importDataMenus.Add(new ImportDataMenu()
                    {
                        Sort = dataMenus.First(x => x.TypeDataTag.GroupName == groupName).TypeDataTag.Sort,
                        GroupName = groupName,
                        SubMethodMenus = groupNameDataMenus.GroupBy(x => x.TypeDataTag).OrderBy(x => x.Key.Sort).ToList()
                    });
                }
            }
            else
            {
                importDataMenus.Add(new ImportDataMenu()
                {
                    Sort = 1,
                    GroupName = "数据驱动",
                    SubMethodMenus = dataMenus.GroupBy(x => x.TypeDataTag).OrderBy(x => x.Key.Sort).ToList()
                });
            }

            this.ImportDataMenus = new ObservableCollection<ImportDataMenu>(importDataMenus.OrderBy(x => x.Sort));
            if (!Directory.Exists(SystemConfig.FileDataBase))//判断是否存在
            {
                //TODO 执行驱动备份数据库
                //Directory.CreateDirectory(SystemConfig.FileDataBase);//创建新路径
            }
            //获取数据库备份文件集合
            //TODO 执行驱动备份数据库
            //var dataBaseNames = Directory.GetFiles(SystemConfig.FileDataBase, "*.bak");
            //foreach (var item in dataBaseNames)
            //{
            //    var dataBaseName = item.Replace(SystemConfig.FileDataBase, "");
            //    var info = dataMenus.Where(x => x.BackDataBaseFileName == dataBaseName);
            //    foreach (var value in info)
            //    {
            //        value.IsExecute = true;
            //    }
            //}
            this.SelectedImportDataMenu = this.ImportDataMenus.FirstOrDefault();
        }
        #endregion
        #endregion

        #region # Events方法
        #region # 显示遮罩事件方法——void Handle(BusyIndicatorEvent busyIndicatorEvent)
        /// <summary>
        /// 显示遮罩事件方法
        /// </summary>
        /// <param name="busyIndicatorEvent">事件参数类</param>
        public override void Handle(BusyIndicatorEvent busyIndicatorEvent)
        {
            Application.Current.BeginInvoke(() =>
            {
                this.IsBusy = busyIndicatorEvent.IsBusy;
                this.BusyContent = busyIndicatorEvent.BusyContent;
                BusyIndicator.BusyOperation(this.IsBusy, this.BusyContent);
            });
        }
        #endregion
        #region # 显示消息事件方法——void Handle(MessageEvent eventData)
        /// <summary>
        /// 显示消息事件方法
        /// </summary>
        public override void Handle(MessageEvent eventData)
        {
            switch (eventData.MessageType)
            {
                case MessageType.Info:
                    Growl.Info(eventData.Message);
                    break;
                case MessageType.Success:
                    Growl.Success(eventData.Message);
                    break;
                case MessageType.Warning:
                    Growl.Warning(eventData.Message);
                    break;
                case MessageType.Error:
                    Growl.Error(eventData.Message);
                    break;
                case MessageType.Ask:
                    Growl.Ask(eventData.Message, (f1) =>
                    {
                        return true;
                    });
                    break;
                case MessageType.Fatal:
                    Growl.Fatal(eventData.Message);
                    break;
            }
        }
        #endregion
        #endregion
    }

    public class ImportDataMenu : PropertyChangedBase
    {
        /// <summary>
        /// 顺序
        /// </summary>
        public int Sort { get; set; }

        /// <summary>
        /// 显示名称
        /// </summary>
        public string GroupName { get; set; }

        /// <summary>
        /// 子方法菜单
        /// </summary>
        public List<IGrouping<DataTagAttribute, DataMenu>> SubMethodMenus { get; set; }
    }
}
